﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.WebTesting;
using QA.TFS.Utils;

namespace QA.TFS.Rules.Extraction
{
    public class RegExExtraction : ExtractionRule
    {
        RegExHelper helper;

        private String _Regex = "";
        public String Regex
        {
            get
            {
                return _Regex;
            }
            set
            {
                _Regex = value;
            }
        }

        private bool _PassOnError = false;

        [DefaultValue(false)]
        public bool PassOnError
        {
            get { return _PassOnError; }
            set { _PassOnError = value; }
        }


        private Boolean _UseSingleline = true;
        public Boolean UseSingleline
        {
            get
            {
                return _UseSingleline;
            }
            set
            {
                _UseSingleline = value;
            }
        }

        private Boolean _UseIngoreCase = true;
        public Boolean UseIngoreCase
        {
            get
            {
                return _UseIngoreCase;
            }
            set
            {
                _UseIngoreCase = value;
            }
        }

        private String _UseMatch = "first";
        public String UseMatch
        {
            get
            {
                return _UseMatch;
            }
            set
            {
                _UseMatch = value;
            }
        }

        private int _ParameterGroup = 0;
        public int ParameterGroup
        {
            get
            {
                return _ParameterGroup;
            }
            set
            {
                _ParameterGroup = value;
            }
        }

        private Match choose_match(List<Match> metconditions)
        {
            int index;
            if (metconditions.Count > 0)
            {
                if (_UseMatch == "first")
                {
                    return metconditions[0];
                }
                else if (_UseMatch == "last")
                {
                    return metconditions[metconditions.Count - 1];
                }
                else if (_UseMatch == "random")
                {
                    Random rand = new Random(DateTime.Now.Millisecond);
                    return metconditions[rand.Next(0, metconditions.Count)];
                }
                else if (int.TryParse(_UseMatch, out index))
                {
                    if (metconditions.Count > index)
                    {
                        return metconditions[index];
                    }
                }
                throw new Exception("Invalid UseMatch field in Extraction");
            }
            throw new Exception("No matches found in Extraction");
        }

        public RegExExtraction()
        {
        }

        void helper_OnMatchNotFound(EventArgs e)
        {
            if (!_PassOnError)
            {
                ((ExtractionEventArgs)e).Success = false;
                ((ExtractionEventArgs)e).Message = this.ContextParameterName + " not found";
            }
        }

        void helper_OnMatchFound(MatchCollection matches, EventArgs e)
        {
            List<Match> metconditions = new List<Match>();
            foreach (Match match in matches)
            {
                if (match.Groups.Count > _ParameterGroup + 1)
                {
                    metconditions.Add(match);
                }
            }

            ((ExtractionEventArgs)e).WebTest.Context.Add(this.ContextParameterName, choose_match(metconditions).Groups[_ParameterGroup + 1].Value);
            ((ExtractionEventArgs)e).Success = true;
        }

        public override void Extract(object sender, ExtractionEventArgs e)
        {
            if (e.Response.HtmlDocument != null)
            {
                base.ContextParameterName = ContextParameterHelper.replaceContextParameters(e.WebTest.Context, base.ContextParameterName);

                helper = new RegExHelper();
                helper.OnMatchFound += new RegExHelper.MatchDelegate(helper_OnMatchFound);
                helper.OnMatchNotFound += new RegExHelper.MatchErrorDelegate(helper_OnMatchNotFound);

                //do work to find result   
                //if (helper.Exists(_Regex, @"([a-zA-Z0-9]*\$[a-zA-Z0-9]*)"))
                //    _Regex = _Regex.Replace("$", "\\$");
                if (_Regex.Contains("$"))
                    _Regex = _Regex.Replace("$", "\\$");

                helper.Regex = _Regex;
                helper.UseIgnoreCase = _UseIngoreCase;
                helper.UseSingleline = _UseSingleline;

                helper.ExtractValue(e.Response.BodyString, e);
            }
        }
    }
}
